package com.bj58.mis.apm.server.statistics.service.impl;

import com.bj58.mis.apm.server.core.util.JsonUtil;
import com.bj58.mis.apm.server.statistics.dto.rowkey.RowkeyStats;
import com.bj58.mis.apm.server.statistics.mapper.RowkeyStatsMapper;
import com.bj58.mis.apm.server.statistics.service.BaseService;
import com.bj58.mis.apm.server.statistics.service.RowkeyStatsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author: wangxw
 * @Date: 2018/7/5 9:56
 */
@Service
public class RowkeyStatsServiceImpl extends BaseService<RowkeyStatsMapper> implements RowkeyStatsService {

    @Override
    public List<RowkeyStats> getRowkeyStatsByMd5(String md5) {
        Map<String, Object> log = this.mapper.getQueryLogByMd5(md5);
        if(log == null){
            return new ArrayList<>();
        }
        List<String> groupList = Arrays.asList(((String)log.get("groupList")).split(","));
        List<String> filterList = Arrays.asList(((String)log.get("filterList")).split(","));
        Long cuboid = (Long)log.get("cuboid");
        String cubeId = (String)log.get("cubeId");
        List<RowkeyStats> rowkeyStatsList = this.mapper.queryRowkeyStatsNoTimes(cubeId);

        //处理baseNum
        //处理状态
        String cuboName = getCuboName(cuboid, rowkeyStatsList.size());
        for(int i = 0 ; i < rowkeyStatsList.size() ; i++){
            RowkeyStats rk = rowkeyStatsList.get(i);
            int status = 0;
            status += groupList.contains(rk.getRowkey()) ? 2 : 0;
            status += filterList.contains(rk.getRowkey()) ? 1 : 0;
            if(status == 0){
                status = cuboName.charAt(i) == '1' ? 4 : 0;
            }
            if(status == 0){
                status = 5;
            }
            rk.setStatus(""+status);
        }

        //处理baseNum
        Map<String, Long> baseNumMap = queryBaseNumMap(cubeId);
        rowkeyStatsList.forEach(rk -> {
            rk.setBaseNum(baseNumMap.get(rk.getRowkey()));
        });

        return rowkeyStatsList;
    }

    @Override
    public List<RowkeyStats> getRowkeyStatsByCube(String cubeId) {
        //查询rowkey - 维度
        List<RowkeyStats> rowkeyStatsList = this.mapper.queryRowKeyStats(cubeId);

        Set<Long> cuboidSet = this.mapper.queryCuboids(cubeId);

        if(cuboidSet != null && cuboidSet.size() > 0){
            String cuboName = getCubeName(cuboidSet, rowkeyStatsList.size());
            for(int i = 0 ; i < rowkeyStatsList.size() ; i++){
                RowkeyStats rk = rowkeyStatsList.get(i);
                int status = 0;
                status += (rk.getGroupCount() != null && rk.getGroupCount().longValue() > 0) ? 2 : 0;
                status += (rk.getFilterCount() != null && rk.getFilterCount().longValue() > 0) ? 1 : 0;
                if(status == 0){
                    status = cuboName.charAt(i) == '1' ? 4 : 0;
                }
                if(status == 0){
                    status = 5;
                }
                rk.setStatus(""+status);
            }
        }else{
            rowkeyStatsList.forEach(rk -> {
                rk.setStatus("5");
            });
        }
        //处理baseNum
        Map<String, Long> baseNumMap = queryBaseNumMap(cubeId);
        rowkeyStatsList.forEach(rk -> {
            rk.setBaseNum(baseNumMap.get(rk.getRowkey()));
        });

        return rowkeyStatsList;
    }

    /**
     * 返回固定长度的前补0二进制字符串
     * @param cuboid
     * @param size
     * @return
     */
    private String getCuboName(Long cuboid, int size) {
        return String.format("%0"+size+"d", Long.parseLong(Long.toBinaryString(cuboid)));
    }

    private String getCubeName(Set<Long> cuboidSet, int size){
        Long result = 0L;
        for(Long l : cuboidSet){
            result = result | l;
        }
        return getCuboName(result, size);
    }

    private Map<String, Long> queryBaseNumMap(String cubeId){
        Map<String, Long> baseNumMap = new HashMap<>();
        List<String> baseNum = this.mapper.queryRowkeyBaseNum(cubeId);
        if(baseNum != null && baseNum.size() > 0) {
            baseNum.forEach(s -> {
                if(StringUtils.isNotEmpty(s)) {
                    List<List> list = JsonUtil.fromArrayJson(s, List.class);
                    list.forEach(l -> {
                        Long x = baseNumMap.get((String) l.get(0));
                        baseNumMap.put((String) l.get(0), (x == null ? 0L : x) + ((Double) l.get(1)).longValue());
                    });
                }
            });
        }
        return baseNumMap;
    }
}
